﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Service.Domain.Conventions
{
    public abstract class BaseConvention<T> : IConvention<T> where T : class
    {
        private string sqlPrefix;

        protected string SqlPrefix { get => string.IsNullOrWhiteSpace(sqlPrefix) ? "" : $"{sqlPrefix}."; }

        public IConvention<T> WithSqlPrefix(string prefix)
        {
            this.sqlPrefix = prefix;
            return this;
        }

        public virtual ConventionGroup<T> And(IConvention<T> condition)
        {
            return this.CreateGroup(ConventionType.AND, this, condition);
        }

        public virtual ConventionGroup<T> Or(IConvention<T> condition)
        {
            return this.CreateGroup(ConventionType.OR, this, condition);
        }

        private ConventionGroup<T> CreateGroup(ConventionType type, IConvention<T> left, IConvention<T> right)
        {
            ConventionGroup<T> group = new ConventionGroup<T>(type, left, right);
            return group;
        }

        public abstract Expression<Func<T, bool>> ToExpression();

        public abstract string ToSql();

        public virtual Func<T, bool> ToAction()
        {
            return this.ToExpression().Compile();
        }
    }
}
